package com.paic.mhis.hcpms.quota.exportword.biz.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.paic.mhis.hcpms.common.document.util.Constant;
import com.paic.mhis.hcpms.quota.calculationreport.kpiinterface.biz.service.KpiCoreDataService;
import com.paic.mhis.hcpms.quota.calculationreport.kpiinterface.dto.KpiBaseDTO;
import com.paic.mhis.hcpms.quota.calculationreport.kpiinterface.dto.KpiConditionDTO;
import com.paic.mhis.hcpms.quota.calculationreport.kpiinterface.dto.KpiGradeDTO;
import com.paic.mhis.hcpms.quota.calculationreport.kpiinterface.dto.KpiMedicalOrgDTO;
import com.paic.mhis.hcpms.quota.calculationreport.kpiinterface.dto.KpiSociationDTO;
import com.paic.mhis.hcpms.quota.exportword.biz.service.AutoGetFeeMedRelatedService;
import com.paic.mhis.hcpms.quota.exportword.utils.GeneralMethods;
import com.paic.mhis.hcpms.quota.exportword.utils.WordReportCalculateHelper;
import com.paic.mhis.hcpms.quota.settlement.common.Constants;
import com.paic.mhis.hcpms.quota.settlement.common.KpiValueConst;

/**
 * Description: 获取住院门诊总费用和者药费占比
 */
@Service("autoGetFeeMedRelatedService")
public class AutoGetFeeMedRelatedServiceImpl implements AutoGetFeeMedRelatedService {

	@Autowired
	private KpiCoreDataService kpiCoreDataService;

	private GeneralMethods generalMethods = GeneralMethods.getInstance();

	private WordReportCalculateHelper helper = WordReportCalculateHelper.getInstance();

	/**
	 * Description: 住院的总费用数据查询
	 * 
	 * @paramMap <String, Object> paramsMap
	 * @return Map<String, Object>
	 */
	@Override
	public Map<String, Object> getHosFeeToRtf(Map<String, Object> paramsMap, Map<String, Object> limitValue) {
		setKpiValueParams(paramsMap, limitValue);
		String wordType = paramsMap.get("type").toString();
		paramsMap.put("visitType", KpiValueConst.VISIT_HOS);
		paramsMap.put("kpiCode", KpiValueConst.KPI0001);
		Map<String, Object> resultMap = null;
		if (Constant.BRANCH_TYPE_ZERO.equals(wordType)) {
			resultMap = queryFirstPartInfoToRtf(paramsMap);
		} else if (Constant.BRANCH_TYPE_ONE.equals(wordType)) {
			resultMap = querySecendPartInfoToRtf(paramsMap);
		} else if (Constant.BRANCH_TYPE_TWO.equals(wordType)) {
			resultMap = queryThirdPartInfoToRtf(paramsMap);
		} else {
			resultMap = new HashMap<String, Object>();
		}
		turnKpiMapToResultMap(paramsMap, resultMap);
		return resultMap;
	}

	/**
	 * Description: 门诊下的总费用查询
	 * 
	 * @param paramsMap
	 * @return Map<String, Object>
	 */
	@Override
	public Map<String, Object> getOutFeeToRtf(Map<String, Object> paramsMap, Map<String, Object> limitValue) {
		setKpiValueParams(paramsMap, limitValue);
		String wordType = paramsMap.get("type").toString();
		paramsMap.put("visitType", KpiValueConst.VISIT_OUT);
		paramsMap.put("kpiCode", KpiValueConst.KPI0001);
		Map<String, Object> resultMap = null;
		if (Constant.BRANCH_TYPE_ZERO.equals(wordType)) {
			resultMap = queryFirstPartInfoToRtf(paramsMap);
		} else if (Constant.BRANCH_TYPE_ONE.equals(wordType)) {
			resultMap = querySecendPartInfoToRtf(paramsMap);
		} else if (Constant.BRANCH_TYPE_TWO.equals(wordType)) {
			resultMap = queryThirdPartInfoToRtf(paramsMap);
		} else {
			resultMap = new HashMap<String, Object>();
		}
		turnKpiMapToResultMap(paramsMap, resultMap);
		return resultMap;
	}

	/**
	 * Description: 住院的医保费用占比查询
	 * 
	 * @param paramsMap
	 * @return Map<String, Object>
	 */
	@Override
	public Map<String, Object> getHosMedToRtf(Map<String, Object> paramsMap, Map<String, Object> limitValue) {
		setKpiValueParams(paramsMap, limitValue);
		String wordType = paramsMap.get("type").toString();
		paramsMap.put("visitType", KpiValueConst.VISIT_HOS);
		paramsMap.put("kpiCode", KpiValueConst.KPI0002);
		Map<String, Object> resultMap = null;
		if (Constant.BRANCH_TYPE_ZERO.equals(wordType)) {
			resultMap = queryFirstPartInfoToRtf(paramsMap);
		} else if (Constant.BRANCH_TYPE_ONE.equals(wordType)) {
			resultMap = querySecendPartInfoToRtf(paramsMap);
		} else if (Constant.BRANCH_TYPE_TWO.equals(wordType)) {
			resultMap = queryThirdPartInfoToRtf(paramsMap);
		} else {
			resultMap = new HashMap<String, Object>();
		}
		turnKpiMapToResultMap(paramsMap, resultMap);
		return resultMap;
	}

	/**
	 * Description: 门诊的医保费用占比
	 * 
	 * @param paramsMap
	 * @return Map<String, Object>
	 */
	@Override
	public Map<String, Object> getOutMedToRtf(Map<String, Object> paramsMap, Map<String, Object> limitValue) {
		setKpiValueParams(paramsMap, limitValue);
		String wordType = paramsMap.get("type").toString();
		paramsMap.put("visitType", KpiValueConst.VISIT_OUT);
		paramsMap.put("kpiCode", KpiValueConst.KPI0002);
		Map<String, Object> resultMap = null;
		if (Constant.BRANCH_TYPE_ZERO.equals(wordType)) {
			resultMap = queryFirstPartInfoToRtf(paramsMap);
		} else if (Constant.BRANCH_TYPE_ONE.equals(wordType)) {
			resultMap = querySecendPartInfoToRtf(paramsMap);
		} else if (Constant.BRANCH_TYPE_TWO.equals(wordType)) {
			resultMap = queryThirdPartInfoToRtf(paramsMap);
		} else {
			resultMap = new HashMap<String, Object>();
		}
		turnKpiMapToResultMap(paramsMap, resultMap);
		return resultMap;
	}

	/**
	 * Description: 查询rtf第一部分的数据
	 * 
	 * @param paramsMap
	 * @return Map<String, Object>
	 */
	private Map<String, Object> queryFirstPartInfoToRtf(Map<String, Object> paramsMap) {
		String endMonth = generalMethods.replacTimeFormate(paramsMap.get("currentDate").toString());
		String kpiCode = paramsMap.get("kpiCode").toString();
		String regionCode = paramsMap.get("regionCode").toString();
		KpiConditionDTO c = new KpiConditionDTO();
		c.setSociationCode(regionCode);
		List<String> vl = new ArrayList<String>();
		vl.add(KpiValueConst.VISIT_HOS);
		vl.add(KpiValueConst.VISIT_OUT);
		c.setVisitTypeList(vl);
		List<String> kl = new ArrayList<String>();
		kl.add(kpiCode);
		c.setKpiCodeList(kl);
		c.setPeriod(KpiValueConst.MONTH);
		String startMonth = helper.getStartDate(endMonth, -Constant.MONTH_THIRTYFIVE);
		c.setKpiTimeStart(startMonth);
		c.setKpiTimeEnd(endMonth);
		// 查询数据库
		List<KpiSociationDTO> dataList = kpiCoreDataService.queryKpiBySoc(c);
		Map<String, Object> resultMap = conventListToMap(changeSocKpiToBase(dataList), startMonth, endMonth, paramsMap);
		return resultMap;
	}

	/**
	 * Description: 查询rtf第二部分的数据
	 * 
	 * @param paramsMap
	 * @return Map<String, Object>
	 */
	private Map<String, Object> querySecendPartInfoToRtf(Map<String, Object> paramsMap) {
		// 设置查询条件
		String visitType = paramsMap.get("visitType").toString();
		String month = paramsMap.get("currentDate").toString();
		String regionCode = paramsMap.get("regionCode").toString();
		KpiConditionDTO kpiConditionDTO = new KpiConditionDTO();
		kpiConditionDTO.setVisitType(visitType);
		kpiConditionDTO.setKpiTime(month);
		List<String> kpiCodeList = new ArrayList<String>();
		kpiCodeList.add(KpiValueConst.KPI0001);
		kpiCodeList.add(KpiValueConst.KPI0002);
		kpiConditionDTO.setKpiCodeList(kpiCodeList);
		kpiConditionDTO.setPeriod(Constants.perion_13); // 按照月份
		kpiConditionDTO.setSociationCode(regionCode);

		List<String> levelList = new ArrayList<String>();
		levelList.add(Constants.type_4);
		levelList.add(Constants.type_3);
		levelList.add(Constants.type_2);

		kpiConditionDTO.setGradeList(levelList);

		List<KpiGradeDTO> kpiGradeList = this.kpiCoreDataService.queryKpiByGrade(kpiConditionDTO);

		KpiConditionDTO kpi0002Con = helper.getKpiConditionByKpiCode(paramsMap, KpiValueConst.KPI0002);
		KpiConditionDTO kpi0001Con = helper.getKpiConditionByKpiCode(paramsMap, KpiValueConst.KPI0001);
		KpiSociationDTO medTotalRate = (KpiSociationDTO) this.kpiCoreDataService.querySingleKpiBySoc(kpi0002Con);
		KpiSociationDTO medTotalFee = (KpiSociationDTO) this.kpiCoreDataService.querySingleKpiBySoc(kpi0001Con);
		Map<String, Object> resultMap = createMapByGrade(kpiGradeList, paramsMap, medTotalRate, medTotalFee);
		return resultMap;
	}

	/**
	 * Description: 查询rtf第三部分的数据
	 * 
	 * @param paramsMap
	 * @return Map<String, Object>
	 */
	private Map<String, Object> queryThirdPartInfoToRtf(Map<String, Object> paramsMap) {
		// 获取查询条件的参数
		KpiConditionDTO c = new KpiConditionDTO();
		String endMonth = generalMethods.replacTimeFormate(paramsMap.get("currentDate").toString());
		String kpiCode = paramsMap.get("kpiCode").toString();
		String orgCode = paramsMap.get("medicalOrgCode").toString();
		String regionCode = paramsMap.get("regionCode").toString();
		c.setOrgCode(orgCode);
		c.setSociationCode(regionCode);
		List<String> vl = new ArrayList<String>();
		vl.add(KpiValueConst.VISIT_HOS);
		vl.add(KpiValueConst.VISIT_OUT);
		c.setVisitTypeList(vl);
		List<String> kl = new ArrayList<String>();
		kl.add(kpiCode);
		c.setKpiCodeList(kl);
		c.setPeriod(KpiValueConst.MONTH);
		String startMonth = helper.getStartDate(endMonth, -Constant.MONTH_THIRTYFIVE);
		c.setKpiTimeStart(startMonth);
		c.setKpiTimeEnd(endMonth);

		List<KpiMedicalOrgDTO> dataList = kpiCoreDataService.queryKpiByOrg(c);

		return conventListToMap(changeOrgKpiToBase(dataList), startMonth, endMonth, paramsMap);
	}

	@SuppressWarnings("unchecked")
	private Map<String, Object> conventListToMap(List<KpiBaseDTO> dataList, String startMonth, String endMonth,
			Map<String, Object> paramsMap) {
		String visitType = paramsMap.get("visitType").toString();
		Map<String, Object> dataMap = getCalculateDataMap(dataList, visitType, startMonth, endMonth, paramsMap);

		// 将查询数据封装到List
		List<BigDecimal> periodList = (List<BigDecimal>) dataMap.get("periodList");
		List<BigDecimal> chainList = (List<BigDecimal>) dataMap.get("chainList");
		List<BigDecimal> totalList = (List<BigDecimal>) dataMap.get("totalList");

		// 同期平均值计算
		Map<String, Object> avgDataMap = getAvgData(periodList, chainList, totalList);
		List<BigDecimal> avgList = (List<BigDecimal>) avgDataMap.get("avgList");
		// List<BigDecimal> avgPeriodList = (List<BigDecimal>)
		// avgDataMap.get("avgPeriodList");
		// List<BigDecimal> avgChainList = (List<BigDecimal>)
		// avgDataMap.get("avgChainList");

		//
		BigDecimal total = totalList.get(totalList.size() - Constant.MONTH_FIRST);
		BigDecimal period = periodList.get(periodList.size() - Constant.MONTH_FIRST);
		BigDecimal chain = chainList.get(chainList.size() - Constant.MONTH_FIRST);

		List<BigDecimal> recentOneYear = helper.createSetListValue(Constant.MONTH_TWELVE, new BigDecimal(0));
		List<BigDecimal> periodLine = helper.createSetListValue(Constant.MONTH_TWELVE, new BigDecimal(0));
		List<BigDecimal> chainLine = helper.createSetListValue(Constant.MONTH_TWELVE, new BigDecimal(0));

		// 计算平均值的预测
		List<BigDecimal> forecastLine = new ArrayList<BigDecimal>();
		// 当年的费用总额
		forecastLine.add(total);
		for (int i = 0; i < Constant.MONTH_TWELVE; i++) {
			getOneYearLine(totalList, recentOneYear, i);
			getOneYearLine(periodList, periodLine, i);
			getOneYearLine(chainList, chainLine, i);
		}

		// 计算12个月的平均值
		Map<String, Object> avgRateMap = getAvgRate(periodLine, chainLine);
		// BigDecimal avgPeriodRate = (BigDecimal)
		// avgRateMap.get("avgPeriodRate");
		BigDecimal avgChainRate = (BigDecimal) avgRateMap.get("avgChainRate");

		// 预测总值
		for (int i = 0; i < Constant.MONTH_THIRD; i++) {
			// 前三年同期平均值*(1+过去12个月平均环比增长率)
			getCastLine(avgList, avgChainRate, forecastLine, i);
		}

		// 同比环比预测
		List<BigDecimal> forecastPeriodLine = helper.getPeriodRatioPredict(forecastLine, totalList, periodLine);
		// 环比计算公式
		List<BigDecimal> forecastChainLine = helper.getChainRatioPredict(forecastLine, chainLine);

		// 将数据封装在map中返回
		Map<String, Object> resultMap = new HashMap<String, Object>();
		// 按照k0_2_1_1_Fee的格式返回键值对
		String keyPrefix = formatKey(paramsMap);
		// 根据情况来确认resultMap的键
		String keyMiddle = confirmResultMap(paramsMap);
		// 计算比率是否异常
		setResultMapUnusualRatio(resultMap, period, chain, paramsMap, keyMiddle);
		// 判断3个月内是否存在异常

		BigDecimal[] yoyLimits = new BigDecimal[2];
		BigDecimal[] momLimits = new BigDecimal[2];
		boolean healthFlag1 = getYoyLimits(paramsMap, yoyLimits);
		boolean healthFlag2 = getMomLimits(paramsMap, momLimits);
		String message = helper.getRisk(forecastPeriodLine, forecastChainLine, yoyLimits, momLimits, healthFlag1
				&& healthFlag2);

		resultMap.put(keyPrefix + keyMiddle + "_end", helper.toFixedPercent(total));
		resultMap.put(keyPrefix + keyMiddle + "_yoy_end", helper.toFixedPercent(this.helper.getAbsVaule(period)));
		resultMap.put(keyPrefix + keyMiddle + "_mom_end", helper.toFixedPercent(this.helper.getAbsVaule(chain)));
		resultMap.put(keyPrefix + keyMiddle + "_zjynList_end", helper.toFixedPercentList(recentOneYear));
		resultMap.put(keyPrefix + keyMiddle + "_gqsnList_end", helper.toFixedPercentList(avgList));
		resultMap.put(keyPrefix + keyMiddle + "_wlsyList_end", helper.toFixedPercentList(forecastLine));
		resultMap.put(keyPrefix + keyMiddle + "_yoyList_end", helper.toFixedPercentList(periodLine));
		resultMap.put(keyPrefix + keyMiddle + "_momList_end", helper.toFixedPercentList(chainLine));
		resultMap.put(keyPrefix + keyMiddle + "_yoy_ycList_end", helper.toFixedPercentList(forecastPeriodLine));
		resultMap.put(keyPrefix + keyMiddle + "_mom_ycList_end", helper.toFixedPercentList(forecastChainLine));
		resultMap.put(keyPrefix + keyMiddle + "_health_flag2_end", message);
		return resultMap;
	}

	// 前三年同期环比平均值*(1+过去12个月平均环比增长率)
	private void getCastLine(List<BigDecimal> avgOneYear, BigDecimal avgRate, List<BigDecimal> forecastLine, int i) {
		forecastLine.add((avgRate.add(new BigDecimal(1))).multiply(avgOneYear.get(i)));
	}

	private void getOneYearLine(List<BigDecimal> totalList, List<BigDecimal> oneYearLineData, int i) {
		oneYearLineData.set(i, totalList.get(totalList.size() + i - Constant.MONTH_TWELVE));
	}

	// 将各种KpiDTO转化成KpiBaseDTO
	private List<KpiBaseDTO> changeSocKpiToBase(List<KpiSociationDTO> dataList) {
		List<KpiBaseDTO> baseList = new ArrayList<KpiBaseDTO>();
		for (KpiSociationDTO dto : dataList) {
			if (dto == null) {
				baseList.add(new KpiBaseDTO());
			}
			baseList.add(dto);
		}
		return baseList;
	}

	// 将各种KpiDTO转化成KpiBaseDTO
	private List<KpiBaseDTO> changeOrgKpiToBase(List<KpiMedicalOrgDTO> dataList) {
		List<KpiBaseDTO> baseList = new ArrayList<KpiBaseDTO>();
		for (KpiMedicalOrgDTO dto : dataList) {
			if (dto == null) {
				baseList.add(new KpiBaseDTO());
			}
			baseList.add(dto);
		}
		return baseList;
	}

	private Map<String, Object> createMapByGrade(List<KpiGradeDTO> kpiGradeList, Map<String, Object> paramsMap,
			KpiSociationDTO medTotalRate, KpiSociationDTO medTotalFee) {
		String[] grade4 = { "一级及以下医院", "0.00", "0.00", "0.00", "0.00", "0.00", "0.00" };
		String[] grade3 = { "二级医院", "0.00", "0.00", "0.00", "0.00", "0.00", "0.00" };
		String[] grade2 = { "三级医院", "0.00", "0.00", "0.00", "0.00", "0.00", "0.00" };
		String[] totalValue = { "合计", "0.00", "", "", "", "", "" };
		String totalFeeKpiValue = "0.00";
		String totalPercentKpiValue = "0.00";
		for (KpiGradeDTO dto : kpiGradeList) {
			if (Constants.type_4.equals(dto.getGrade())) {
				judGradeToSetVal(grade4, dto);
			} else if (Constants.type_3.equals(dto.getGrade())) {
				judGradeToSetVal(grade3, dto);
			} else if (Constants.type_2.equals(dto.getGrade())) {
				judGradeToSetVal(grade2, dto);
			}
		}
		totalValue[0] = "合计";
		if (medTotalFee != null) {
			// 合计保留万为单位
			totalFeeKpiValue = helper.toFixedPercent(helper.yuanToTenThousands(helper.filterNullValue(medTotalFee
					.getKpiValue())));
		}
		totalValue[1] = totalFeeKpiValue;
		if (medTotalRate != null) {
			totalPercentKpiValue = helper.toFixedPercent(medTotalRate.getKpiValue());
		}
		totalValue[4] = totalPercentKpiValue;
		List<Object> tableList = new ArrayList<Object>();
		tableList.add(grade2);
		tableList.add(grade3);
		tableList.add(grade4);
		tableList.add(totalValue);
		Map<String, Object> resultMap = new HashMap<String, Object>();

		String key = formatKey(paramsMap);
		resultMap.put(key + "tableList_end", tableList);

		return resultMap;
	}

	private void judGradeToSetVal(String[] grade, KpiGradeDTO dto) {
		if (KpiValueConst.KPI0001.equals(dto.getKpiCode())) {
			setGradeVal(grade, dto);
		} else {
			setMoreGradeVal(grade, dto);
		}
	}

	private void setGradeVal(String[] grade, KpiGradeDTO dto) {
		// 各部分之间的对比保留万为单位
		grade[1] = (helper.toFixedTwoPercent(helper.yuanToTenThousands(helper.filterNullValue(dto.getKpiValue()))));
		grade[2] = (helper.toFixedTwoPercent(helper.filterNullValue(dto.getPeriodRatio())));
		grade[3] = (helper.toFixedTwoPercent(helper.filterNullValue(dto.getChainRatio())));
	}

	private void setMoreGradeVal(String[] grade, KpiGradeDTO dto) {
		grade[4] = (helper.toFixedTwoPercent(helper.filterNullValue(dto.getKpiValue())));
		grade[5] = (helper.toFixedTwoPercent(helper.filterNullValue(dto.getPeriodRatio())));
		grade[6] = (helper.toFixedTwoPercent(helper.filterNullValue(dto.getChainRatio())));
	}

	// 计算
	private Map<String, Object> getCalculateDataMap(List<KpiBaseDTO> dataList, String visitType, String startMonth,
			String endMonth, Map<String, Object> paramsMap) {
		Map<String, Object> calculateDataMap = new HashMap<String, Object>();
		// 将查询数据封装到List
		Map<String, Integer> orderMap = helper.createOrderList(startMonth, endMonth);
		List<BigDecimal> periodList = helper.createSetListValue(orderMap.size(), new BigDecimal(0));
		List<BigDecimal> chainList = helper.createSetListValue(orderMap.size(), new BigDecimal(0));
		// 总额
		List<BigDecimal> totalList = helper.createSetListValue(orderMap.size(), new BigDecimal(0));
		String type = paramsMap.get("type").toString();
		for (KpiBaseDTO dto : dataList) {
			String kpiCode = dto.getKpiCode();
			BigDecimal kpiValue = dto.getKpiValue();
			BigDecimal periodRatio = dto.getPeriodRatio(); // 同比
			BigDecimal chainRatio = dto.getChainRatio(); // 环比
			String kpiTime = generalMethods.replacTimeFormate(dto.getKpiTime());
			// 总额
			if (KpiValueConst.KPI0001.equals(kpiCode) && dto.getVisitType().equals(visitType)) {
				// 总额中住院和门诊
				periodList.set(orderMap.get(kpiTime), helper.filterNullValue(periodRatio));
				chainList.set(orderMap.get(kpiTime), helper.filterNullValue(chainRatio));
				if (Constant.ZERO.equals(type)) {
					totalList.set(orderMap.get(kpiTime), helper.yuan2Yi(helper.filterNullValue(kpiValue)));
				} else {
					totalList.set(orderMap.get(kpiTime), helper.yuanToTenThousands(helper.filterNullValue(kpiValue)));
				}

			}
			// 医保费用占比
			if (KpiValueConst.KPI0002.equals(kpiCode) && dto.getVisitType().equals(visitType)) {
				// 区分住院和门诊的数据存放
				periodList.set(orderMap.get(kpiTime), helper.filterNullValue(periodRatio));
				chainList.set(orderMap.get(kpiTime), helper.filterNullValue(chainRatio));
				totalList.set(orderMap.get(kpiTime), helper.filterNullValue(kpiValue));
			}
		}
		calculateDataMap.put("orderMap", orderMap);
		calculateDataMap.put("periodList", periodList);
		calculateDataMap.put("chainList", chainList);
		calculateDataMap.put("totalList", totalList);
		return calculateDataMap;
	}

	private Map<String, Object> getAvgData(List<BigDecimal> periodList, List<BigDecimal> chainList,
			List<BigDecimal> totalList) {
		Map<String, Object> avgDataMap = new HashMap<String, Object>();

		// 同期平均
		List<BigDecimal> avgList = helper.createSetListValue(Constant.MONTH_TWELVE, new BigDecimal(0));
		List<BigDecimal> avgPeriodList = helper.createSetListValue(Constant.MONTH_TWELVE, new BigDecimal(0));
		List<BigDecimal> avgChainList = helper.createSetListValue(Constant.MONTH_TWELVE, new BigDecimal(0));
		// 计算同期平均值
		for (int i = 0; i < Constant.MONTH_TWELVE; i++) {
			if (totalList != null) {
				avgList.set(i, totalList.get(i).add(totalList.get(i + Constant.MONTH_TWELVE))
						.add(totalList.get(i + 24)).divide(new BigDecimal(3), 2, BigDecimal.ROUND_HALF_UP));
			}
			if (periodList != null) {
				avgPeriodList.set(i,
						periodList.get(i).add(periodList.get(i + Constant.MONTH_TWELVE)).add(periodList.get(i + 24))
								.divide(new BigDecimal(3), 2, BigDecimal.ROUND_HALF_UP));
			}
			if (chainList != null) {
				avgChainList.set(i,
						chainList.get(i).add(chainList.get(i + Constant.MONTH_TWELVE)).add(chainList.get(i + 24))
								.divide(new BigDecimal(3), 2, BigDecimal.ROUND_HALF_UP));
			}
		}
		avgDataMap.put("avgList", avgList);
		avgDataMap.put("avgPeriodList", avgPeriodList);
		avgDataMap.put("avgChainList", avgChainList);
		return avgDataMap;
	}

	private Map<String, Object> getAvgRate(List<BigDecimal> periodLine, List<BigDecimal> chainLine) {
		Map<String, Object> avgRateMap = new HashMap<String, Object>();
		// 计算过去12个月的平均同比的环比的增长率
		// 计算过去12个月的环比的环比增长率
		BigDecimal subPeriodRate = new BigDecimal(0);
		BigDecimal subChainRate = new BigDecimal(0);
		for (int i = 0; i < periodLine.size(); i++) {
			subPeriodRate = subPeriodRate.add(periodLine.get(i)
					.divide(new BigDecimal(100), 8, BigDecimal.ROUND_HALF_UP));
			subChainRate = subChainRate.add(chainLine.get(i).divide(new BigDecimal(100), 8, BigDecimal.ROUND_HALF_UP));
		}

		BigDecimal avgPeriodRate = subPeriodRate.divide(new BigDecimal(periodLine.size()), 8, BigDecimal.ROUND_HALF_UP);
		BigDecimal avgChainRate = subChainRate.divide(new BigDecimal(chainLine.size()), 8, BigDecimal.ROUND_HALF_UP);

		avgRateMap.put("avgPeriodRate", avgPeriodRate);
		avgRateMap.put("avgChainRate", avgChainRate);
		return avgRateMap;
	}

	private String formatKey(Map<String, Object> paramsMap) {
		String type = paramsMap.get("type").toString();
		String kpiCode = paramsMap.get("kpiCode").toString();
		String visitType = paramsMap.get("visitType").toString();
		// k0_3_1_1_fee
		StringBuilder key = new StringBuilder("k");
		key.append(type).append("_");
		if (KpiValueConst.VISIT_HOS.equals(visitType)) {
			key.append("2");
		} else if (KpiValueConst.VISIT_OUT.equals(visitType)) {
			key.append("3");
		}
		key.append("_1_");
		if (KpiValueConst.KPI0001.equals(kpiCode)) {
			key.append("1_");
		} else if (KpiValueConst.KPI0002.equals(kpiCode)) {
			key.append("2_");
		}
		return key.toString();
	}

	private String confirmResultMap(Map<String, Object> paramsMap) {
		String kpiCode = paramsMap.get("kpiCode").toString();
		StringBuilder keyMiddle = new StringBuilder();
		if (KpiValueConst.KPI0001.equals(kpiCode)) {
			keyMiddle.append("fee");
		} else if (KpiValueConst.KPI0002.equals(kpiCode)) {
			keyMiddle.append("f");
		}
		return keyMiddle.toString();
	}

	private void setResultMapUnusualRatio(Map<String, Object> resultMap, BigDecimal period, BigDecimal chain,
			Map<String, Object> paramsMap, String keyMiddle) {
		String key = formatKey(paramsMap);
		if (helper.compareToZero(period)) {
			resultMap.put(key + keyMiddle + "_yoy_flag_end", "降低");
		} else {
			resultMap.put(key + keyMiddle + "_yoy_flag_end", "增加");
		}
		if (helper.compareToZero(chain)) {
			resultMap.put(key + keyMiddle + "_mom_flag_end", "降低");
		} else {
			resultMap.put(key + keyMiddle + "_mom_flag_end", "增加");
		}

		BigDecimal[] yoyLimits = new BigDecimal[2];
		BigDecimal[] momLimits = new BigDecimal[2];
		boolean healthYoyFlag = getYoyLimits(paramsMap, yoyLimits);
		boolean healthMomFlag = getMomLimits(paramsMap, momLimits);

		if (healthYoyFlag) {
			setHealthYoyFlagNull(resultMap, key, keyMiddle);
		}

		if (healthMomFlag) {
			setHealthMomFlagNull(resultMap, key, keyMiddle);
		}

		if (healthYoyFlag || healthMomFlag) {
			return;
		}

		boolean periodUnNormal = helper.judgeIndUnusual(period, yoyLimits[0], yoyLimits[1]);
		boolean chainUnNormal = helper.judgeIndUnusual(chain, momLimits[0], momLimits[1]);

		setMoreUnusualMsg(resultMap, keyMiddle, key, periodUnNormal, chainUnNormal);
	}

	private void setMoreUnusualMsg(Map<String, Object> resultMap, String keyMiddle, String key, boolean periodUnNormal,
			boolean chainUnNormal) {
		if (periodUnNormal) {
			resultMap.put(key + keyMiddle + "_yoy_result_end", "已超出");
		} else {
			resultMap.put(key + keyMiddle + "_yoy_result_end", "未超出");
		}

		if (chainUnNormal) {
			resultMap.put(key + keyMiddle + "_mom_result_end", "已超出");
		} else {
			resultMap.put(key + keyMiddle + "_mom_result_end", "未超出");
		}

		if (periodUnNormal || chainUnNormal) {
			resultMap.put(key + keyMiddle + "_health_flag_end", "可能存在异常");
		} else {
			resultMap.put(key + keyMiddle + "_health_flag_end", "无明显异常");
		}
	}

	private void setHealthYoyFlagNull(Map<String, Object> resultMap, String key, String keyMiddle) {
		resultMap.put(key + keyMiddle + "_health_flag_end", " ");
		resultMap.put(key + keyMiddle + "_yoy_result_end", " ");
	}

	private void setHealthMomFlagNull(Map<String, Object> resultMap, String key, String keyMiddle) {
		resultMap.put(key + keyMiddle + "_health_flag_end", " ");
		resultMap.put(key + keyMiddle + "_mom_result_end", " ");
	}

	private boolean getYoyLimits(Map<String, Object> paramsMap, BigDecimal[] limits) {
		if (KpiValueConst.KPI0001.equals(paramsMap.get("kpiCode"))) {
			String yoyUpperLimit = (String) paramsMap.get("KPI0001_yoy_upper_end");
			String yoyLowerLimit = (String) paramsMap.get("KPI0001_yoy_lower_end");
			if (isStrsNull(yoyUpperLimit, yoyLowerLimit)) {
				return true;
			}
			limits[0] = new BigDecimal(yoyUpperLimit);
			limits[1] = new BigDecimal(yoyLowerLimit);
		} else {
			String yoyUpperLimit = (String) paramsMap.get("KPI0002_yoy_upper_end");
			String yoyLowerLimit = (String) paramsMap.get("KPI0002_yoy_lower_end");
			if (isStrsNull(yoyUpperLimit, yoyLowerLimit)) {
				return true;
			}
			limits[0] = new BigDecimal(yoyUpperLimit);
			limits[1] = new BigDecimal(yoyLowerLimit);
		}
		return false;
	}

	private boolean getMomLimits(Map<String, Object> paramsMap, BigDecimal[] limits) {
		if (KpiValueConst.KPI0001.equals(paramsMap.get("kpiCode"))) {
			String momUpperLimit = (String) paramsMap.get("KPI0001_mom_upper_end");
			String momLowerLimit = (String) paramsMap.get("KPI0001_mom_lower_end");
			if (isStrsNull(momUpperLimit, momLowerLimit)) {
				return true;
			}
			limits[0] = new BigDecimal(momUpperLimit);
			limits[1] = new BigDecimal(momLowerLimit);
		} else {
			String momUpperLimit = (String) paramsMap.get("KPI0002_mom_upper_end");
			String momLowerLimit = (String) paramsMap.get("KPI0002_mom_lower_end");
			if (isStrsNull(momUpperLimit, momLowerLimit)) {
				return true;
			}
			limits[0] = new BigDecimal(momUpperLimit);
			limits[1] = new BigDecimal(momLowerLimit);
		}
		return false;
	}

	private boolean isStrsNull(String upperLimit, String lowerLimit) {
		return StringUtils.isBlank(upperLimit) || StringUtils.isBlank(lowerLimit);
	}

	private void setKpiValueParams(Map<String, Object> paramsMap, Map<String, Object> limitValue) {
		paramsMap.put("KPI0001_yoy_upper_end", limitValue.get("KPI0001_yoy_upper_end"));
		paramsMap.put("KPI0001_yoy_lower_end", limitValue.get("KPI0001_yoy_lower_end"));
		paramsMap.put("KPI0001_mom_upper_end", limitValue.get("KPI0001_mom_upper_end"));
		paramsMap.put("KPI0001_mom_lower_end", limitValue.get("KPI0001_mom_lower_end"));
		paramsMap.put("KPI0002_yoy_upper_end", limitValue.get("KPI0002_yoy_upper_end"));
		paramsMap.put("KPI0002_yoy_lower_end", limitValue.get("KPI0002_yoy_lower_end"));
		paramsMap.put("KPI0002_mom_upper_end", limitValue.get("KPI0002_mom_upper_end"));
		paramsMap.put("KPI0002_mom_lower_end", limitValue.get("KPI0002_mom_lower_end"));
	}

	private void turnKpiMapToResultMap(Map<String, Object> paramsMap, Map<String, Object> resultMap) {
		if (KpiValueConst.KPI0001.equals(paramsMap.get("kpiCode"))) {
			resultMap.put("KPI0001_yoy_upper_end", " ");
			resultMap.put("KPI0001_yoy_lower_end", " ");
			resultMap.put("KPI0001_mom_upper_end", " ");
			resultMap.put("KPI0001_mom_lower_end", " ");
			setLimitToResult((String) paramsMap.get("KPI0001_yoy_upper_end"), "KPI0001_yoy_upper_end", resultMap);
			setLimitToResult((String) paramsMap.get("KPI0001_yoy_lower_end"), "KPI0001_yoy_lower_end", resultMap);
			setLimitToResult((String) paramsMap.get("KPI0001_mom_upper_end"), "KPI0001_mom_upper_end", resultMap);
			setLimitToResult((String) paramsMap.get("KPI0001_mom_lower_end"), "KPI0001_mom_lower_end", resultMap);
		} else {
			resultMap.put("KPI0002_yoy_upper_end", " ");
			resultMap.put("KPI0002_yoy_lower_end", " ");
			resultMap.put("KPI0002_mom_upper_end", " ");
			resultMap.put("KPI0002_mom_lower_end", " ");
			setLimitToResult((String) paramsMap.get("KPI0002_yoy_upper_end"), "KPI0002_yoy_upper_end", resultMap);
			setLimitToResult((String) paramsMap.get("KPI0002_yoy_lower_end"), "KPI0002_yoy_lower_end", resultMap);
			setLimitToResult((String) paramsMap.get("KPI0002_mom_upper_end"), "KPI0002_mom_upper_end", resultMap);
			setLimitToResult((String) paramsMap.get("KPI0002_mom_lower_end"), "KPI0002_mom_lower_end", resultMap);
		}
	}

	private void setLimitToResult(String paramsLimit, String resultKey, Map<String, Object> resultMap) {
		if (StringUtils.isBlank(paramsLimit)) {
			return;
		}
		resultMap.put(resultKey, paramsLimit);
	}

}
